package com.example.questionsystem.modules.qu.util;

import lombok.Data;
import org.docx4j.TextUtils;
import org.docx4j.dml.CTBlip;
import org.docx4j.dml.CTBlipFillProperties;
import org.docx4j.dml.wordprocessingDrawing.Anchor;
import org.docx4j.dml.wordprocessingDrawing.Inline;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.*;
import org.springframework.web.multipart.MultipartFile;

import javax.xml.bind.JAXBElement;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WordDocumentExtractor {

    public static String extractFullContent(MultipartFile file) throws Exception {
        try (InputStream inputStream = file.getInputStream()) {
            // 加载Word文档
            WordprocessingMLPackage wordPackage = WordprocessingMLPackage.load(inputStream);

            Document document = wordPackage.getMainDocumentPart().getJaxbElement();
            StringBuilder sb = new StringBuilder();
            extractTextFromDocument(document, sb);
            return sb.toString();
        }
    }
    private static void extractTextFromDocument(Document document, StringBuilder sb) {
        List<Object> content = document.getBody().getContent();
        for (Object obj : content) {
            if (obj instanceof P) {
                extractTextFromParagraph((P) obj, sb);
                sb.append("\n"); // 段落结束换行
            } else if (obj instanceof JAXBElement) {
                Object value = ((JAXBElement<?>) obj).getValue();
                if (value instanceof P) {
                    extractTextFromParagraph((P) value, sb);
                    sb.append("\n");
                }
            }
            // 可以添加其他元素类型的处理（如表格）
        }
    }
    private static void extractTextFromParagraph(P paragraph, StringBuilder sb) {
        List<Object> runs = paragraph.getContent();
        for (Object runObj : runs) {
            if (runObj instanceof R) {
                R run = (R) runObj;
                List<Object> runContents = run.getContent();
                for (Object contentObj : runContents) {
                    if (contentObj instanceof JAXBElement) {
                        Object value = ((JAXBElement<?>) contentObj).getValue();
                        if (value instanceof Text) {
                            sb.append(((Text) value).getValue());
                        }
                    } else if (contentObj instanceof Text) {
                        sb.append(((Text) contentObj).getValue());
                    } else if (contentObj instanceof Br) {
                        sb.append("\n"); // 换行符
                    }
                    // 图片等对象可以在这里添加占位符
                }
            }
        }
    }
    private static void extractContent(MainDocumentPart mainPart, DocumentContent documentContent) {
        List<Object> content = mainPart.getContent();
        
        for (Object obj : content) {
            if (obj instanceof P) {
                // 处理段落
                documentContent.addParagraph(processParagraph((P) obj, mainPart));
            } else if (obj instanceof Tbl) {
                // 处理表格
                documentContent.addTable(processTable((Tbl) obj, mainPart));
            }
            // 可以添加其他元素类型（如页眉/页脚）的处理
        }
    }

    private static DocumentParagraph processParagraph(P paragraph, MainDocumentPart mainPart) {
        DocumentParagraph docPara = new DocumentParagraph();
        
        // 获取段落属性
        PPr pPr = paragraph.getPPr();
        if (pPr != null) {
            // 提取段落样式
            docPara.setStyle(extractParagraphStyle(pPr));
        }
        
        // 处理段落内的内容
        for (Object runObj : paragraph.getContent()) {
            if (runObj instanceof R) {
                R run = (R) runObj;
                DocumentRun docRun = processRun(run, mainPart);
                docPara.addRun(docRun);
            }
        }
        
        return docPara;
    }

    private static DocumentRun processRun(R run, MainDocumentPart mainPart) {
        DocumentRun docRun = new DocumentRun();
        RPr rPr = run.getRPr();
        
        // 提取文本格式
        if (rPr != null) {
            docRun.setTextStyle(extractTextStyle(rPr));
        }
        
        // 处理运行内容
        for (Object contentObj : run.getContent()) {
            if (contentObj instanceof JAXBElement) {
                JAXBElement<?> jaxbElement = (JAXBElement<?>) contentObj;
                Object value = jaxbElement.getValue();
                
                if (value instanceof Text) {
                    // 文本内容
                    Text text = (Text) value;
                    docRun.addText(text.getValue());
                } else if (value instanceof Drawing) {
                    // 图片/图表
                    Drawing drawing = (Drawing) value;
//                    DocumentImage image = extractImage(drawing, mainPart);
//                    if (image != null) {
//                        docRun.setImage(image);
//                    }
                }
            } else if (contentObj instanceof Br) {
                // 换行符
                docRun.addText("\n");
            }
        }
        
        return docRun;
    }

//    private static DocumentImage extractImage(Drawing drawing, MainDocumentPart mainPart) {
//        try {
//            // 获取 Drawing 中的第一个内联图片
//            Object drawingObject = drawing.getAnchorOrInline().get(0);
//
//            // 处理内联图片 (inline)
//            if (drawingObject instanceof Inline) {
//                Inline inline =
//                        (Inline) drawingObject;
//
//                // 获取图片信息
//                CTBlipFillProperties blipFill =
//                        inline.getGraphic().getGraphicData().getPic().getBlipFill();
//                CTBlip blip = blipFill.getBlip();
//                String relationshipId = blip.getEmbed();
//
//                // 获取图片二进制数据
//                BinaryPartAbstractImage imagePart = (BinaryPartAbstractImage) mainPart.getRelationshipsPart()
//                        .getPart(relationshipId);
//
//                DocumentImage docImage = new DocumentImage();
//                docImage.setRelationshipId(relationshipId);
//                docImage.setContentType(imagePart.getContentType());
//                docImage.setData(imagePart.getBytes());
//
//                // 获取图片尺寸
//                docImage.setWidth(inline.getExtent().getCx());
//                docImage.setHeight(inline.getExtent().getCy());
//
//                // 异步上传图片
//                uploadImageAsync(docImage);
//
//                // 设置临时占位文本
//                docImage.setPlaceholderText("[图片上传中...]");
//
//                return docImage;
//            }
//            // 处理浮动图片 (anchor) - 可选
//            else if (drawingObject instanceof Anchor) {
//                Anchor anchor =
//                        (Anchor) drawingObject;
//
//                // 处理逻辑类似内联图片...
//                // 这里可以添加对浮动图片的支持
//            }
//        } catch (Exception e) {
//            System.err.println("图片提取失败: " + e.getMessage());
//            e.printStackTrace();
//        }
//        return null;
//    }
    private static String getImageExtension(BinaryPartAbstractImage imagePart) {
        String contentType = imagePart.getContentType();
        if (contentType == null) return "dat";
        
        switch (contentType) {
            case "image/png": return "png";
            case "image/jpeg": return "jpg";
            case "image/gif": return "gif";
            case "image/bmp": return "bmp";
            default: return contentType.split("/")[1];
        }
    }

    private static Map<String, String> extractParagraphStyle(PPr pPr) {
        Map<String, String> style = new HashMap<>();
        
        // 对齐方式
        if (pPr.getJc() != null) {
            style.put("alignment", pPr.getJc().getVal().value());
        }
        
        // 缩进
        if (pPr.getInd() != null) {
            style.put("indent", String.valueOf(pPr.getInd().getLeft()));
        }
        
        // 行距
        if (pPr.getSpacing() != null) {
            style.put("lineSpacing", String.valueOf(pPr.getSpacing().getLine()));
        }
        
        return style;
    }

    private static Map<String, String> extractTextStyle(RPr rPr) {
        Map<String, String> style = new HashMap<>();
        
        // 字体
        if (rPr.getRFonts() != null) {
            style.put("font", rPr.getRFonts().getAscii());
        }
        
        // 字号
        if (rPr.getSz() != null) {
            // 将BigInteger转换为整数，然后除以2（因为字号单位是半磅）
            int fontSize = rPr.getSz().getVal().intValue() / 2;
            style.put("fontSize", String.valueOf(fontSize));
        }
        
        // 颜色
        if (rPr.getColor() != null) {
            style.put("color", rPr.getColor().getVal());
        }
        
        // 粗体
        if (rPr.getB() != null) {
            style.put("bold", "true");
        }
        
        // 斜体
        if (rPr.getI() != null) {
            style.put("italic", "true");
        }
        
        // 下划线
        if (rPr.getU() != null) {
            style.put("underline", rPr.getU().getVal().value());
        }
        
        return style;
    }

    private static DocumentTable processTable(Tbl table, MainDocumentPart mainPart) {
        DocumentTable docTable = new DocumentTable();
        
        for (Object rowObj : table.getContent()) {
            if (rowObj instanceof Tr) {
                Tr row = (Tr) rowObj;
                DocumentTableRow docRow = new DocumentTableRow();
                
                for (Object cellObj : row.getContent()) {
                    if (cellObj instanceof Tc) {
                        Tc cell = (Tc) cellObj;
                        DocumentTableCell docCell = new DocumentTableCell();
                        
                        // 处理单元格内容
                        for (Object cellContent : cell.getContent()) {
                            if (cellContent instanceof P) {
                                docCell.addParagraph(processParagraph((P) cellContent, mainPart));
                            }
                        }
                        
                        docRow.addCell(docCell);
                    }
                }
                
                docTable.addRow(docRow);
            }
        }
        
        return docTable;
    }

    // 定义文档内容结构类
    @Data
    public static class DocumentContent {
        private List<DocumentParagraph> paragraphs = new ArrayList<>();
        private List<DocumentTable> tables = new ArrayList<>();
        private List<DocumentImage> images = new ArrayList<>();

        public void addParagraph(DocumentParagraph paragraph) {
            this.paragraphs.add(paragraph);
        }

        public void addTable(DocumentTable table) {
            this.tables.add(table);
        }

        public void addImage(DocumentImage image) {
            this.images.add(image);
        }

        // 添加 getter 方法
    }
    @Data
    public static class DocumentParagraph {
        private Map<String, String> style = new HashMap<>();
        private List<DocumentRun> runs = new ArrayList<>();

        public void addRun(DocumentRun run) {
            this.runs.add(run);
        }

        public void setStyle(Map<String, String> style) {
            this.style = style;
        }

        // 添加 getter 方法
    }
    @Data
    public static class DocumentRun {
        private Map<String, String> textStyle = new HashMap<>();
        private StringBuilder textContent = new StringBuilder();
        private DocumentImage image;

        public void addText(String text) {
            textContent.append(text);
        }

        public void setTextStyle(Map<String, String> textStyle) {
            this.textStyle = textStyle;
        }

        public void setImage(DocumentImage image) {
            this.image = image;
        }

        // 添加 getter 方法
    }
    @Data
    public static class DocumentImage {
        private String fileName;
        private String contentType;
        private byte[] data;
        private long width;
        private long height;

        // 添加 setter 和 getter 方法
    }
    @Data
    public static class DocumentTable {
        private List<DocumentTableRow> rows = new ArrayList<>();

        public void addRow(DocumentTableRow row) {
            this.rows.add(row);
        }

        // 添加 getter 方法
    }
    @Data
    public static class DocumentTableRow {
        private List<DocumentTableCell> cells = new ArrayList<>();

        public void addCell(DocumentTableCell cell) {
            this.cells.add(cell);
        }

        // 添加 getter 方法
    }
    @Data
    public static class DocumentTableCell {
        private List<DocumentParagraph> paragraphs = new ArrayList<>();

        public void addParagraph(DocumentParagraph paragraph) {
            this.paragraphs.add(paragraph);
        }

        // 添加 getter 方法
    }
}